/*
 * Author: 李波(Edwin Lee)
 * Date: 2024-08-10 16:21:53
 * FilePath: /mprpc/src/include/public.h
 * LastEditTime: 2024-09-03 15:42:34
 * version: 1.0
 * Description: 公共函数和类
 */

#ifndef __PUBLIC_H__
#define __PUBLIC_H__

#include <string>
#include <string.h>
#include <unistd.h>
#include <stdarg.h>


#ifdef WIN32
#define MKDIR(path) _mkdir(path)
#define SLEEP(mseconds) Sleep(mseconds)
#else
#include <sys/stat.h>
#include <sys/types.h>
#define MKDIR(path) mkdir(path,0755)
#define SLEEP(mseconds) usleep(mseconds*1000)
#endif

//从字符串中去掉头部的空格和\ t，尾部的空格，\ r,\ n，\ t字符，保存到strOut
// 需要保证strOut足够大函数内部不做判断
//strOut不需要清零
//strOut或者strIn为NULL返回false
bool strTrim(char* strOut, const char* strIn) noexcept;

//去掉str头部的空格和\ t，尾部的空格，\ r,\ n，\ t字符
void strTrim(std::string& str) noexcept;

//从路径中去除头部空格，尾部的空格,\\r,\\n,\\t字符，再把路径中的'\\'换成‘/’
//需要保证strOut足够大函数内部不做判断
//strOut不需要清零
void pathTrim(char* pathOut, const char* pathIn) noexcept;

/*
 ********************************************************************************************
 *时间操作类LTime 和一个计时器 LTimer
 ********************************************************************************************
 */
//localtime（）返回静态分配的tm* ，也就是说所有线程操作的是同一个tm* ，因此是线程不安全的
//此处使用安全的localtime_s(WINDOWS),或者localtime_r(LINUX)
#ifdef WIN32
#define SLocaltime(time,result) localtime_s(result,time)
#else
#define SLocaltime(time,result) localtime_r(time,result)
#endif

//struct tm
//{
//    int tm_sec;  /*秒，正常范围0-59， 但允许至61*/
//    int tm_min;  /*分钟，0-59*/
//    int tm_hour; /*小时， 0-23*/
//    int tm_mday; /*日，即一个月中的第几天，1-31*/
//    int tm_mon;  /*月， 从一月算起，0-11*/  1 + p->tm_mon;
//    int tm_year;  /*年， 从1900至今已经多少年*/  1900＋ p->tm_year;
//    int tm_wday; /*星期，一周中的第几天， 从星期日算起，0-6*/
//    int tm_yday; /*从今年1月1日到目前的天数，范围0-365*/
//    int tm_isdst; /*日光节约时间的旗标*/
//};
//
class LTime
{
public:
	//默认构造函数,使用默认构造函数表示获取的是当前时间
	LTime();

	//使用此构造函数表示需要获取time时间戳所表示的时间
	LTime(const time_t* time);
	~LTime();

	//调用getCurrentTime()设置为当前时间
	//isCurrentTime_设置为true
	void setTimeNow();

	//设置为某个时间time
	void setTime(const time_t* time);

	//获取某种格式的日期字符串,成功返回时间字符串，失败返回空字符串
	//默认格式为yyyy-MM-dd hh24:mm:ss的日期字符串
	//如果isCurrentTime_ == true,此函数每次调用都会先调用getCurrentTime()函数刷新当前时间
	//支持以下格式：
	//yyyy-mm-dd hh24:mi:ss
	//yyyy-mm-dd hh24:mi
	//yyyy-mm-dd hh24
	//yyyy-mm-dd
	//yyyy-mm
	//yyyymmddhh24miss
	//yyyymmddhh24mi
	//yyyymmddhh24
	//yyyymmdd
	//hh24miss
	std::string getDate(const char* fmt = nullptr);

	//获取yyyy格式的年字符串
	//此函数在isCurrentTime == true时不会刷新当前时间，若要获取更精准时间请先调用setTimeNow();
	std::string getYear();

	//获取mm格式的月字符串
	//此函数在isCurrentTime == true时不会刷新当前时间，若要获取更精准时间请先调用setTimeNow();
	std::string getMonth();

	//获取dd格式的当月第几天的字符串
	//此函数在isCurrentTime == true时不会刷新当前时间，若要获取更精准时间请先调用setTimeNow();
	std::string getDay();

	//获取hh24格式的小时的字符串
	//此函数在isCurrentTime == true时不会刷新当前时间，若要获取更精准时间请先调用setTimeNow();
	std::string getHour();

	//获取mi格式的分钟的字符串
	//此函数在isCurrentTime == true时不会刷新当前时间，若要获取更精准时间请先调用setTimeNow();
	std::string getMinute();

	//获取ss格式的秒字符串
	//此函数在isCurrentTime == true时不会刷新当前时间，若要获取更精准时间请先调用setTimeNow();
	std::string getSeconds();

private:
	struct tm tm_;

	//是否取当前时间
	bool isCurrentTime_;		

	//把时间设置为当前时间
	void getCurrentTime();


};

/*
 *************************************************************************************
 *dir目录操作的一些函数
 *************************************************************************************
 */
constexpr int MAX_DIR_LENGTH = 320;				//定义目录的路径最大值

//逐级创建嵌套目录
//此方法适用跨平台
//path：目录的路径
//isFileName:此路径是否包含了文件名，true-是，false-不是，默认不含文件名
//返回值：如果目录存在或者不存在但是可以创建成功返回true，创建失败返回false
bool createDir(const char* path, bool isFileName = false);

//打开文件，如果以写的方式打开，会创建文件路径
//FOPEN函数的参数和返回值与fopen库函数完全相同
//开发中用此函数代替fopen
FILE* FOPEN(const char* filename, const char* mode);

//description: 移动或者重命名（文件或文件夹）,如果新的路径上级目录不存在则会自动创建目录
//	注意：如果创建失败会留下新建的目录，函数不会把它们删除）
//param oldpath:需要移动的文件名
//param newpath:新的文件名
//param isFileName:是否是文件名，默认true，如果oldpath是文件夹，此处填false
//param times:如果修改失败，最多尝试的次数
//return {bool}:成功返回true，失败返回false
//Date: 2024-08-23 03:07:23
bool RENAME(const char* oldpath, const char* newpath, bool isFileName = true, const int times=1);

#endif